package com.xiaoma.thread.wait.connectionpool;

import java.util.LinkedList;
import java.util.stream.IntStream;

/**
 * https://segmentfault.com/a/1190000019145922
 * @author xiaomacdut
 * @date 2020年3月7日 下午12:04:02
 */
public class ConnectionPoolOfWaitNotify{
    
    private Integer capacity = 4;// 连接池中的连接数
    LinkedList<Connection> linkedList = new LinkedList<>(); // 连接容器
    
    public ConnectionPoolOfWaitNotify(){
        IntStream.rangeClosed(1, capacity).forEach(i-> {// 构造方法中初始化所有连接
            linkedList.addLast(new Connection("connection-" + i));
        });
    }
    
    // 获取连接
    public Connection getConnectioin(long time) throws InterruptedException{
        synchronized(linkedList){
            if(!linkedList.isEmpty()){// 如果存在，拿走第一个
                return linkedList.removeFirst();
            }
            
            if(time <= 0){// 等到拿到连接再返回
                while(linkedList.isEmpty()){
                    linkedList.wait();
                }
                return linkedList.removeFirst();
            }
            
            long lastTime = System.currentTimeMillis() + time;
            long sleepTime = time;
            while(linkedList.isEmpty() && sleepTime > 0){
                linkedList.wait(sleepTime);
                sleepTime = lastTime - System.currentTimeMillis();
            }
            
            if(!linkedList.isEmpty()){
                return linkedList.removeFirst();
            }else{
                return null;
            }
        }
    }
    
    // 归还连接
    public void revertConnection(Connection connection){
        synchronized(linkedList){
            linkedList.addLast(connection);
            linkedList.notifyAll();// 归还连接后通知其他拿连接的线程
        }
    }
}
